'''
Created on 12/06/2014

@author: Hector
'''


#import threading
import time
import os
from SessionManager import SessionManager
import sys

class SOP:
    '''
    classdocs
    
    '''
    

    def __init__(self, pfilter):
        '''
        Constructor
        '''
        self.filter = pfilter
    
    def mergeAll(self):
            #variables
        try:
            self.corriendo = True
            self.finalFile =self.filter.getOutputPath()+os.path.sep+"merged"+os.path.sep+"merged.txt"
            self.createIfNotExist(self.finalFile)
            self.lines_seen= set()
            self.temp = set()
            self.totalfiles=0
            self.currentfile=0 #Gui/Session
            self.currentInputBufferIteration=0#session only

            paths = os.listdir(self.filter.getInputPath())
            self.files = []
            for p in paths:
                if os.path.isfile(self.filter.getInputPath()+os.path.sep+p):
                    self.files.append(p)
            
            for f in self.files:
                self.totalfiles+=1
                
            print "Files to merge: ", self.files
            self.currentfile+=1
            for infileToOpen in self.files:
                
                self.mergeProcess(infileToOpen)
                    
            self.corriendo = False
            
            
        except KeyboardInterrupt:
                self.interrupt()
            
                
                    
    def interrupt(self):
        self.lines_seen.clear()
        self.temp.clear()
        try:
            self.fout.close()
        except: 
            pass
        try:
            self.corriendo =False
            correct=False
            passwords=["C","S","E"]
            user_input = raw_input("Process Stopped. Do you want to (C)ountinue, (S)ave session or (E)xit?")
            while not correct:
                user_input =user_input.capitalize()
                if user_input in passwords:
                    correct=True
                else:
                    user_input = raw_input("Incorrect key, please try again. Do you want to (C)ountinue, (S)ave session or (E)xit?")
                        
            if user_input == "C":
                self.continueMerge()
            elif user_input == "S":
                self.saveSession()
                print "Session saved!"
                self.interrupt()
            elif user_input == "E":
                print "Exit"
                sys.exit()
            else:
                print "something brong, saving session and exiting"
                self.saveSession()
                sys.exit()
        except KeyboardInterrupt:
            self.interrupt() 
                 
    def continueMergeSession(self, session):
        try:
            self.filter.setInputPath(session["Input path"])
            self.filter.setOutputPath(session["Output path"])
            self.filter.bi= session["Input buffer"]
            self.filter.bi= session["Output buffer"]
            self.filesTemp =[]
            self.filesTemp = session["Listdir"].split(',')
            self.currentfile = session["Current file number"]
            self.currentInputBufferIteration = session["Current in"]
            self.corriendo = True
            self.lines_seen = set()
            self.finalFile =self.filter.getOutputPath()+os.path.sep+"merged"+os.path.sep+"merged.txt"
            self.createIfNotExist(self.finalFile)
            self.temp = set()
            self.files=[]
            self.totalfiles=0
            
            for f in self.filesTemp:
                self.files.append(f.split("'")[1])
                self.totalfiles+=1
            
            self.continuingMerge()
            
        except KeyboardInterrupt:
            self.interrupt()
            
    def continueMerge(self):
            try:
                self.continuingMerge()
                
            except KeyboardInterrupt:
                self.interrupt()    
                
                
    def continuingMerge(self):
        print "Continuing from last flag"
        self.corriendo = True
        file = ""
        current =0        
        for f in self.files:
            current +=1
            if current == self.currentfile:
                file = f
                break   
                    
        file = self.filter.getInputPath()+os.path.sep+file
        self.ContinueMergeFile(file)
        self.currentfile+=1
        #self.createNextU()
        current =0 
        for f in self.files:
            current +=1
            if current >= self.currentfile:
                self.mergeProcess(f)
                
    def mergeProcess(self, f):
        infileToOpen = self.filter.getInputPath()+os.path.sep+f
        print "Current file(",self.currentfile.__str__(),"/",self.totalfiles.__str__(),"): " + f
        self.mergeFile(infileToOpen)
        self.currentfile+=1
            
    def createNextU(self):
        #print "adding input part to unique file list..."
        if not os.path.exists(self.finalFile):
            open(self.finalFile, 'a').close

        with open(self.finalFile,"r") as fin:
                self.temp.clear()
                templines=0
                #print "Loading UWFL by parts"
                for line in fin:
                    if templines<=self.filter.bo:
                        self.temp.add(line)
                        templines+=1
                        #self.totalLines = self.totalLines+1
                    else:
                        mem =((self.temp.__sizeof__()/1024)/1024)
                        mem = mem.__str__()
                        #print self.filter.bo,"kkk unique lines loaded, differencing with incoming part...", " Memory usage: ",mem
                        templines=0
                        self.lines_seen = self.lines_seen.difference(self.temp)
                        self.temp.clear()
                        if not self.lines_seen:
                            break
                        #print "Difference with incoming part done!"
                if self.lines_seen:
                    self.lines_seen = self.lines_seen.difference(self.temp)
                if self.lines_seen:    
                    self.fout= open(self.finalFile,"a")
                    #print "Writing diference to Unique Word File List..."
                    for l in self.lines_seen:
                        self.fout.write(l)
                        #self.totalLines = self.totalLines+1
                    self.fout.close()
                    #print "Write done!"    
      
    def mergeFile(self, file):
        #print "splitting input..."
        self.lines_seen.clear()
        fin = open(file,"r")
        templines=0
        self.currentInputBufferIteration=1#session
        for line in fin:
            if templines <= self.filter.bi:
                if line not in self.lines_seen:
                    templines+=1
                    #self.totalLines = self.totalLines+1
                    self.lines_seen.add(line)
                #else:
                    #self.totalmatches = self.totalmatches+1
            else:
                self.createNextU()
                self.lines_seen.clear()
                templines=0
                self.currentInputBufferIteration+=1#session
               
        fin.close()
        self.createNextU()
        
    def ContinueMergeFile(self, file):
        #print "splitting input..."
        self.lines_seen.clear()
        print "Current file(",self.currentfile.__str__(),"/",self.totalfiles.__str__(),"): " + file
       
        templines=0
        #self.currentInputBufferIteration=1#session
        currInBuffIt=1
        cursor=0
        with open(file,"r") as fin:
            while currInBuffIt<self.currentInputBufferIteration:
                fin.readline()
                cursor+=1
                templines+=1
                if templines >= self.filter.bi:
                    currInBuffIt+=1
                    templines=0
        #current =fin.tell()
            
        templines=0
        #fin.seek(current)
        index=0
        with open(file,"r")as fin:   
            for line in fin:
                index+=1
                if index>=cursor:
                    if templines <= self.filter.bi:
                        if line not in self.lines_seen:
                            templines+=1
                            #self.totalLines = self.totalLines+1
                            self.lines_seen.add(line)
                        #else:
                            #self.totalmatches = self.totalmatches+1
                    else:
                        self.createNextU()
                        self.lines_seen.clear()
                        templines=0
                        self.currentInputBufferIteration+=1#session
                      
        #fin.close()
        self.createNextU()

##funciones
    def createIfNotExist(self, dir):
        if not os.path.exists(os.path.dirname(dir)):
            os.makedirs(os.path.dirname(dir))
            return True
        else:
            return False

    def saveSession(self):
        sm = SessionManager()
        #sm.iniciar()
        sm.save(self.filter.getInputPath(), self.filter.getOutputPath(),self.filter.bi, self.filter.bo, self.files, self.currentfile, self.currentInputBufferIteration)   
###################################################################################

    def showProcess(self):
        temp =0
        times =1
        totalsum =0
        while self.corriendo:
            time.sleep(30)
            average = ((self.totalLines+self.totalmatches)-(temp))/30
            totalsum = average + totalsum
            memory = self.lines_seen.__sizeof__()+self.temp.__sizeof__()
            print "Lines processed: ", self.totalLines,"| Total droped matches: ",self.totalmatches, " | LPS: ", (average), " | Buffer size: ",((memory/1024)/1024)," MB", "| av ",(totalsum/times).__str__(), " | ",(time.strftime("%H:%M:%S"))," H"
            temp = self.totalLines+self.totalmatches
            times = times+1
        print "Vervose ended."
            
                    
                    
                    
                    
                
